package com.guohengspace.mq.utils;

import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName AESUtil
 * @Description AES加解密工具类
 * @Author GuanNing
 * @Date 2022/11/2 15:50
 */
@Slf4j
public class AESUtil {

    public static final String AES_INITIALVECTOR = "0000000000000000";
    private static final String ALGORITHM = "AES";
    private static final String MODE = "AES/CBC/PKCS5Padding";

    public static byte[] encrypt(byte[] data, String key, String iv) throws Exception {
        byte[] keyBytes = Hex2ByteArray(key);
        Key keySpec = new SecretKeySpec(keyBytes, ALGORITHM);

        Cipher cipher = Cipher.getInstance(MODE);
        IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());

        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
        return cipher.doFinal(data);
    }

    public static String encrypt(String toEnc, String key, String iv) throws Exception {
        return toHexString(encrypt(toEnc.getBytes(), key, iv));
    }

    public static byte[] Hex2ByteArray(String stringHEX) {
        byte[] bufferByte = new byte[stringHEX.length() / 2];
        try {
            List<Integer> bufferls = new ArrayList<Integer>();
            Integer j = 0;
            for (int i = 2; i < stringHEX.length() + 2; i = i + 2) {
                bufferls.add(Integer.decode("0x" + stringHEX.substring(j, i)));
                j = i;
            }
            for (int i = 0; i < bufferls.size(); i++) {
                bufferByte[i] = bufferls.get(i).byteValue();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return bufferByte;
    }

    public static String toHexString(byte[] b) {
        StringBuffer buffer = new StringBuffer();
        for (byte ts : b) {
            String hex = Integer.toHexString(ts & 0xff);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            buffer.append(hex);
        }
        return buffer.toString();
    }

    public static String getMD5(String s) {
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            digest.update(s.getBytes());
            byte messageDigest[] = digest.digest();
            return toHexString(messageDigest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String decrypt(byte[] data, String key, String iv) throws Exception {
        byte[] keyBytes = Hex2ByteArray(key);
        Key keySpec = new SecretKeySpec(keyBytes, ALGORITHM);

        Cipher cipher = Cipher.getInstance(MODE);
//		IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes("UTF-8"));
        IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
//		return new String(cipher.doFinal(data), "UTF-8").trim();
        return new String(cipher.doFinal(data)).trim();
    }

    public static String decrypt(String encryptedHEX, String key, String iv) {
        try {
            return decrypt(Hex2ByteArray(encryptedHEX), key, iv);
        } catch (Exception e) {
            log.error("数据解密异常 encryptedHEX: {},key: {},iv: {},exception: {}", encryptedHEX, key, iv, e.getMessage());
            throw new RuntimeException(e);
        }
    }
}
